
#include <iostream>
#include "../inc/logger.h"
#include "../core/command_config.h"
#include "client_config.h"

ClientConfig::ClientConfig()
{
	clientCfg.heartbeatSwitch=1;
	clientCfg.maxHeartBeatTick = 5;
	clientCfg.heartbeat_interval = 3000;
	clientCfg.broken_interval = 3000;
}
bool ClientConfig::ReadConfigFile()
{
	TiXmlElement * root = mDocument->FirstChildElement("configuration");
	if(!root)
	{
		LOG4_ERROR("Parse xml file failed,can't find node[configuration]");
		return false;
	}
    if (!ReadServerCFG(root,clientCfg))
	{
		LOG4_ERROR("Parse xml file failed");
        return false;
	}
    return true;
}

bool ClientConfig::ReadServerCFG(TiXmlElement *root,ClientCFG &clientCfg)
{
	TiXmlElement *client = root->FirstChildElement("client");
	if(!client)
	{
		LOG4_ERROR("Parse xml file failed,can't find node[client]");
        return false;
	}
	else
	{
		const char *str ;
		str = GetNodeValue("appName",client);
		if (str)
			clientCfg.appName=str;
		str = GetNodeValue("appType",client);
		if (str)
			clientCfg.appType=atoi(str);
		str = GetNodeValue("appGroup",client);
		if (str)
			clientCfg.appGroup=atoi(str);
		str = GetNodeValue("auth",client);
		if (str)
			clientCfg.auth=str;
		str = GetNodeValue("uuid",client);
		if (str)
			clientCfg.uuid=str;
		TiXmlElement * pserviceList = client->FirstChildElement("serviceList");
		if(pserviceList != NULL)
		{
			TiXmlElement * pservice = pserviceList->FirstChildElement();
			while(pservice != NULL)
			{		
				str = pservice->FirstChild()->Value();
				if(str != NULL)
				{
					clientCfg.serviceList.push_back(atoi(str));
				}
				pservice = pservice->NextSiblingElement();
			}
		}
		TiXmlElement * psubscribeList = client->FirstChildElement("subscribeList");
		if(psubscribeList != NULL)
		{
			TiXmlElement * ptopic = psubscribeList->FirstChildElement();
			while(ptopic != NULL)
			{
				str = ptopic->FirstChild()->Value();
				if(str != NULL)
				{
					int num=atoi(str);
					if(num!=0 || strcmp(str,"0")==0)
					    clientCfg.subscribeList.push_back(num);
					else
					{
						int cmd=CommandConfig::getInstance().GetCommand(str);
						clientCfg.subscribeList.push_back(cmd);
					}
				}
				ptopic = ptopic->NextSiblingElement();
			}
		}
		TiXmlElement * pdatasync = client->FirstChildElement("datasync");
		if(pdatasync != NULL)
		{
			TiXmlElement * ptopic = pdatasync->FirstChildElement();
			while(ptopic != NULL)
			{
				str = ptopic->FirstChild()->Value();
				if(str != NULL)
				{
					clientCfg.datasync.push_back(atoi(str));
				}
				ptopic = ptopic->NextSiblingElement();
			}
		}
	}
	TiXmlElement *servercfg = root->FirstChildElement("serverGroup");
	if(!servercfg)
    {
		LOG4_ERROR("Parse xml file failed,can't find node[serverGroup]");
        return false;
    }
	TiXmlElement * server = servercfg->FirstChildElement();
	while(server != NULL)
	{
		ServerCFG servertmp;
		server->Attribute("port",&servertmp.port );
		if(server->Attribute("IP") != NULL)
			servertmp.serverIP = string(server->Attribute("IP"));
		else
			servertmp.serverIP = "";
		LOG4_INFO("Parse xml file,ip=%s,port=%d",servertmp.serverIP.c_str(),servertmp.port);
		if(server->Attribute("protocol") != NULL)
			servertmp.protocol = string(server->Attribute("protocol"));
		else
			servertmp.protocol = "tcp";
		if(server->Attribute("role") != NULL)
			servertmp.role = string(server->Attribute("role"));
		else
			servertmp.role = "sender";
		if(server->Attribute("id") != NULL)
			server->Attribute("id",&servertmp.id );
		if(server->Attribute("groupnum") != NULL)
			server->Attribute("groupnum",&servertmp.groupNum );
		if(servertmp.protocol == "tcp")
		    clientCfg.serverGroup.push_back(servertmp);
		else if(servertmp.role == "sender")
		{
			clientCfg.udpSenderCfg=servertmp;
			clientCfg.udpSenderCfg.isValid=true;
		}
		else if(servertmp.role == "receiver")
		{
			clientCfg.udpReceiverCfg=servertmp;
			clientCfg.udpReceiverCfg.isValid=true;
		}
		server = server->NextSiblingElement();
	}
	
	TiXmlElement *connectcfg = root->FirstChildElement("connection");
	if(!connectcfg)
	{
		LOG4_ERROR("Parse xml file failed,can't find node[connection]");
		return false;
	}
	const char * str = GetNodeValue("timeout",connectcfg);
	if(!str)
	{
		return false;
	}
	clientCfg.connect_time_out = atoi(str);

	TiXmlElement *heartbeatcfg = root->FirstChildElement("heartbeat");
	str = GetNodeValue("maxHeartBeatTick",heartbeatcfg);
    if (!str)
        return false;
	clientCfg.maxHeartBeatTick = atoi(str);
	
	str = GetNodeValue("hearbeatinterval",heartbeatcfg);
    if (!str)
        return false;
	clientCfg.heartbeat_interval = atoi(str);

	str = GetNodeValue("brokeninterval",heartbeatcfg);
    if (!str)
        return false;
	clientCfg.broken_interval = atoi(str);

	str = GetNodeValue("switch",heartbeatcfg);
    if (!str)
        return false;
	clientCfg.heartbeatSwitch = atoi(str);

	TiXmlElement *zlibcfg = root->FirstChildElement("zlib");
	str = GetNodeValue("switch",zlibcfg);
    if (!str)
        return false;
	clientCfg.zlibswitch = atoi(str);
	
	str = GetNodeValue("threshold",zlibcfg);
    if (!str)
        return false;
	clientCfg.zlibthreshold = atoi(str);

	TiXmlElement *multipagecfg = root->FirstChildElement("multipage");
	if (multipagecfg)
	{
		str = GetNodeValue("switch", multipagecfg);
		if (str)
			clientCfg.multipageswitch = atoi(str);
		str = GetNodeValue("pagesize", multipagecfg);
		if (str)
			clientCfg.multipagesize = atoi(str);
	}

	TiXmlElement *logcfg = root->FirstChildElement("log");
	if(logcfg)
	{
		str = GetNodeValue("level",logcfg);
		if (str)
			clientCfg.loglevel = atoi(str);
		str = GetNodeValue("filename",logcfg);
		if (str)
			clientCfg.logfilename=str;
		str = GetNodeValue("report",logcfg);
		if (str)
			clientCfg.reportlog=atoi(str);
		str = GetNodeValue("reportlevel",logcfg);
		if (str)
			clientCfg.reportlevel=atoi(str);
	}

	TiXmlElement *performancecfg = root->FirstChildElement("performance");
	if (!performancecfg)
	{
		return false;
	}
    str = GetNodeValue("threadNum",performancecfg);
	if (str)
	{
		clientCfg.threadNum = atoi(str);
		if (clientCfg.threadNum < 3)
			clientCfg.threadNum = 3;
	}
	str = GetNodeValue("buffersize",performancecfg);
    if (str)
        clientCfg.buffersize = atoi(str);
	str = GetNodeValue("sendqueuesize",performancecfg);
    if (str)
		clientCfg.sendqueuesize= atoi(str);
	str = GetNodeValue("recvqueuesize",performancecfg);
    if (str)
		clientCfg.receivequeuesize= atoi(str);
	str = GetNodeValue("messagetimeout", performancecfg);
	if (str)
	{
		clientCfg.msgtimeout = atoi(str);
		if (clientCfg.msgtimeout < 1000)
			clientCfg.msgtimeout = 1000;
	}
	str = GetNodeValue("waittime", performancecfg);
	if (str)
	{
		clientCfg.waittime = atoi(str);
		if (clientCfg.waittime < 3)
			clientCfg.waittime = 3;
	}
	str = GetNodeValue("msginterval", performancecfg);
	if (str)
	{
		clientCfg.msginterval = atoi(str);
	}

	str = GetNodeValue("sendmode",root);
	if (!str)
		clientCfg.sendmode= 0;
	else
		clientCfg.sendmode= atoi(str);

    return true;
}
const char* ClientConfig::GetNodeValue(string name,TiXmlElement *parent)
{
    if (!parent)
        return NULL;
	TiXmlElement *ne = parent->FirstChildElement(name.c_str());

	if (!ne || !ne->FirstChild())
	{
		return NULL;
	}

    return ne->FirstChild()->Value();
}



